/******************************************************************/
/*                                                                */
/*  Winpooch : Windows Watchdog                                   */
/*  Copyright (C) 2004-2006  Benoit Blanchon                      */
/*                                                                */
/*  This program is free software; you can redistribute it        */
/*  and/or modify it under the terms of the GNU General Public    */
/*  License as published by the Free Software Foundation; either  */
/*  version 2 of the License, or (at your option) any later       */
/*  version.                                                      */
/*                                                                */
/*  This program is distributed in the hope that it will be       */
/*  useful, but WITHOUT ANY WARRANTY; without even the implied    */
/*  warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR       */
/*  PURPOSE.  See the GNU General Public License for more         */
/*  details.                                                      */
/*                                                                */
/*  You should have received a copy of the GNU General Public     */
/*  License along with this program; if not, write to the Free    */
/*  Software Foundation, Inc.,                                    */
/*  675 Mass Ave, Cambridge, MA 02139, USA.                       */
/*                                                                */
/******************************************************************/


/******************************************************************/
/* Build configuration                                            */
/******************************************************************/

#define	TRACE_LEVEL	2


/******************************************************************/
/* Includes                                                       */
/******************************************************************/

// module's interface
#define _NTUNDOC_C
#include "NtUndoc.h"

// project's headers
#include "ImgInfo.h"
#include "SystInfo.h"
#include "Trace.h"


/******************************************************************/
/* Exported data                                                  */
/******************************************************************/

NTUNDOC_NAMESPACE ntundoc ;


/******************************************************************/
/* Internal macros                                                */
/******************************************************************/

#define arraysize(a) (sizeof(a)/sizeof((a)[0]))


/******************************************************************/
/* Internal data types                                            */
/******************************************************************/

typedef struct {
  LPCTSTR           szOsVersion ;
  DWORD             dwTimeStamp ;
  NTUNDOC_NAMESPACE offsets ;
} NTUNDOC_OSVERSION ;


/******************************************************************/
/* Internal data                                                  */
/******************************************************************/

static NTUNDOC_OSVERSION g_aOsVersion[] = 
  {
    {
      TEXT("ntkrnlpa 5.00.2195.1"),
      0x384D5A86,
      {
        .NtCreateProcess           = (void*) 0x000DEE96,
        .NtCreateProcessEx         = NULL,
        .NtCreateSection           = (void*) 0x000C6DCA,
        .NtTerminateProcess        = (void*) 0x000DFCA6,
        .NtQueryInformationFile    = (void*) 0x000A685A,
        .NtQueryKey                = (void*) 0x0010EB36,
        .NtQueryValueKey           = (void*) 0x0010EDCC,
        .NtSetInformationFile      = (void*) 0x000A6EA8,
        .NtSetValueKey             = (void*) 0x0010F45E,
        .ObpFreeObject             = (void*) 0x000D548E,
        .PspTerminateProcess       = (void*) 0x000DFE28,
        .swprintf                  = (void*) 0x0005EC20,
        .ZwOpenProcess             = (void*) 0x0002E094,
        .ZwProtectVirtualMemory    = (void*) 0x0002E164,
        .ZwReadVirtualMemory       = (void*) 0x0002E434,
      }
    },
    {
      TEXT("ntoskrnl 5.00.2195.1"),
      0x384D9B17,
      {
        .NtCreateProcess           = (void*) 0x000AD948,
        .NtCreateProcessEx         = NULL,
        .NtCreateSection           = (void*) 0x000AEFF6,
        .NtTerminateProcess        = (void*) 0x000A2FAC,
        .NtQueryInformationFile    = (void*) 0x000AE525,
        .NtQueryKey                = (void*) 0x0009923A,
        .NtQueryValueKey           = (void*) 0x0009A077,
        .NtSetInformationFile      = (void*) 0x000C1308,
        .NtSetValueKey             = (void*) 0x000B8D90,
        .ObpFreeObject             = (void*) 0x00095B7F,
        .PspTerminateProcess       = (void*) 0x000FB3EB,
        .swprintf                  = (void*) 0x0005DEE2,
        .ZwOpenProcess             = (void*) 0x00000E5A,
        .ZwProtectVirtualMemory    = (void*) 0x00000F2A,
        .ZwReadVirtualMemory       = (void*) 0x000011FA,
      }
    },
    {
      TEXT("ntkrnlpa 5.00.2195.6717"),
      0x3EE650C9,
      {
        .NtCreateProcess           = (void*) 0x000E29A6,
        .NtCreateProcessEx         = NULL,
        .NtCreateSection           = (void*) 0x000C9F3E,
        .NtTerminateProcess        = (void*) 0x000E3A0E,
        .NtQueryInformationFile    = (void*) 0x000A9DD6,
        .NtQueryKey                = (void*) 0x001133AC,
        .NtQueryValueKey           = (void*) 0x00113642,
        .NtSetInformationFile      = (void*) 0x000AA424,
        .NtSetValueKey             = (void*) 0x00113CD4,
        .ObpFreeObject             = (void*) 0x000D8A1E,
        .PspTerminateProcess       = (void*) 0x000E3B90,
        .swprintf                  = (void*) 0x00062890,
        .ZwOpenProcess             = (void*) 0x0002EA60,
        .ZwProtectVirtualMemory    = (void*) 0x0002EB30,
        .ZwReadVirtualMemory       = (void*) 0x0002EE00,
      }
    },
    {
      TEXT("ntoskrnl 5.00.2195.6717"),
      0x3EE6C002,
      {
        .NtCreateProcess           = (void*) 0x000A9212,
        .NtCreateProcessEx         = NULL,
        .NtCreateSection           = (void*) 0x0009F7F1,
        .NtTerminateProcess        = (void*) 0x000A9BF3,
        .NtQueryInformationFile    = (void*) 0x000987C1,
        .NtQueryKey                = (void*) 0x000B2FC0,
        .NtQueryValueKey           = (void*) 0x000B3138,
        .NtSetInformationFile      = (void*) 0x00098C08,
        .NtSetValueKey             = (void*) 0x000B32F4,
        .ObpFreeObject             = (void*) 0x000A6852,
        .PspTerminateProcess       = (void*) 0x000FBDBA,
        .swprintf                  = (void*) 0x00061E42,
        .ZwOpenProcess             = (void*) 0x00000EDA,
        .ZwProtectVirtualMemory    = (void*) 0x00000FAA,
        .ZwReadVirtualMemory       = (void*) 0x0000127A,
      }
    },
    {
      TEXT("ntkrnlpa 5.1.2600.0 (xpclient.010817-1148)"),
      0x3B7D82F5,
      {
        .NtCreateProcess           = (void*) 0x000D90DE,
        .NtCreateProcessEx         = (void*) 0x000D9036,
        .NtCreateSection           = (void*) 0x000B36D0,
        .NtTerminateProcess        = (void*) 0x000DA28C,
        .NtQueryInformationFile    = (void*) 0x00086096,
        .NtQueryKey                = (void*) 0x00127F7E,
        .NtQueryValueKey           = (void*) 0x00124D76,
        .NtSetInformationFile      = (void*) 0x00086686,
        .NtSetValueKey             = (void*) 0x0012533A,
        .ObpFreeObject             = (void*) 0x000C9708,
        .PspTerminateProcess       = (void*) 0x000DA3FE,
        .swprintf                  = (void*) 0x00056070,
        .ZwOpenProcess             = (void*) 0x000241D8,
        .ZwProtectVirtualMemory    = (void*) 0x00024304,
        .ZwReadVirtualMemory       = (void*) 0x000246D8,
      }
    },
    {
      TEXT("ntoskrnl 5.1.2600.0 (xpclient.010817-1148)"),
      0x3B7DE38F,
      {
        .NtCreateProcess           = (void*) 0x000CA61D,
        .NtCreateProcessEx         = (void*) 0x000B0346,
        .NtCreateSection           = (void*) 0x000A11D5,
        .NtTerminateProcess        = (void*) 0x0009C6DC,
        .NtQueryInformationFile    = (void*) 0x000A6210,
        .NtQueryKey                = (void*) 0x0008B86B,
        .NtQueryValueKey           = (void*) 0x000A5D81,
        .NtSetInformationFile      = (void*) 0x000B181D,
        .NtSetValueKey             = (void*) 0x00093215,
        .ObpFreeObject             = (void*) 0x000A0975,
        .PspTerminateProcess       = (void*) 0x00136477,
        .swprintf                  = (void*) 0x00021D42,
        .ZwOpenProcess             = (void*) 0x0003B7EE,
        .ZwProtectVirtualMemory    = (void*) 0x0003B91A,
        .ZwReadVirtualMemory       = (void*) 0x0003BCEE,
      }
    },
    {
      TEXT("ntkrnlpa 5.1.2600.1106 (xpsp1.020828-1920)"),
      0x3D6DD59C,
      {
        .NtCreateProcess           = (void*) 0x000DCD3C,
        .NtCreateProcessEx         = (void*) 0x000DCC94,
        .NtCreateSection           = (void*) 0x000B6D42,
        .NtTerminateProcess        = (void*) 0x000DE3A6,
        .NtQueryInformationFile    = (void*) 0x0008909A,
        .NtQueryKey                = (void*) 0x0012BAC6,
        .NtQueryValueKey           = (void*) 0x001288C0,
        .NtSetInformationFile      = (void*) 0x0008968A,
        .NtSetValueKey             = (void*) 0x00128E84,
        .ObpFreeObject             = (void*) 0x000CD280,
        .PspTerminateProcess       = (void*) 0x000DE518,
        .swprintf                  = (void*) 0x00057350,
        .ZwOpenProcess             = (void*) 0x00024C84,
        .ZwProtectVirtualMemory    = (void*) 0x00024DB0,
        .ZwReadVirtualMemory       = (void*) 0x00025184,
      }
    },
    {
      TEXT("ntoskrnl 5.1.2600.1106 (xpsp1.020828-1920)"),
      0x3D6DE35C,
      {
        .NtCreateProcess           = (void*) 0x000DA8B3,
        .NtCreateProcessEx         = (void*) 0x000BC950,
        .NtCreateSection           = (void*) 0x000ABB92,
        .NtTerminateProcess        = (void*) 0x000BDC32,
        .NtQueryInformationFile    = (void*) 0x000B0514,
        .NtQueryKey                = (void*) 0x0009F460,
        .NtQueryValueKey           = (void*) 0x000AF3FB,
        .NtSetInformationFile      = (void*) 0x000BE589,
        .NtSetValueKey             = (void*) 0x0009E2DC,
        .ObpFreeObject             = (void*) 0x000AB072,
        .PspTerminateProcess       = (void*) 0x000F1EC6,
        .swprintf                  = (void*) 0x00023783,
        .ZwOpenProcess             = (void*) 0x0003B280,
        .ZwProtectVirtualMemory    = (void*) 0x0003B348,
        .ZwReadVirtualMemory       = (void*) 0x00064F44,
      }
    },
    {
      TEXT("ntkrnlpa 5.1.2600.1149 (xpsp2.021108-1929)"),
      0x3DF3AC19,
      {
        .NtCreateProcess           = (void*) 0x000DCE96,
        .NtCreateProcessEx         = (void*) 0x000DCDEE,
        .NtCreateSection           = (void*) 0x000B6EC2,
        .NtTerminateProcess        = (void*) 0x000DE500,
        .NtQueryInformationFile    = (void*) 0x0008921A,
        .NtQueryKey                = (void*) 0x0012BC34,
        .NtQueryValueKey           = (void*) 0x00128A2E,
        .NtSetInformationFile      = (void*) 0x0008980A,
        .NtSetValueKey             = (void*) 0x00128FF2,
        .ObpFreeObject             = (void*) 0x000CD400,
        .PspTerminateProcess       = (void*) 0x000DE672,
        .swprintf                  = (void*) 0x000574D0,
        .ZwOpenProcess             = (void*) 0x00024DA4,
        .ZwProtectVirtualMemory    = (void*) 0x00024ED0,
        .ZwReadVirtualMemory       = (void*) 0x000252A4,
      }
    },
    {
      TEXT("ntoskrnl 5.1.2600.1149 (xpsp2.021108-1929)"),
      0x3DF3AC07,
      {
        .NtCreateProcess           = (void*) 0x000D70E0,
        .NtCreateProcessEx         = (void*) 0x000D7038,
        .NtCreateSection           = (void*) 0x000B1CB0,
        .NtTerminateProcess        = (void*) 0x000D874A,
        .NtQueryInformationFile    = (void*) 0x0008421A,
        .NtQueryKey                = (void*) 0x00125E6C,
        .NtQueryValueKey           = (void*) 0x00122C66,
        .NtSetInformationFile      = (void*) 0x0008480A,
        .NtSetValueKey             = (void*) 0x0012322A,
        .ObpFreeObject             = (void*) 0x000C7642,
        .PspTerminateProcess       = (void*) 0x000D88BC,
        .swprintf                  = (void*) 0x000542C0,
        .ZwOpenProcess             = (void*) 0x00024CEC,
        .ZwProtectVirtualMemory    = (void*) 0x00024E18,
        .ZwReadVirtualMemory       = (void*) 0x000251EC,
      }
    },
    {
      TEXT("ntkrnlpa 5.1.2600.1634 (xpsp2.050301-1526)"),
      0x42250A90,
      {
        .NtCreateProcess           = (void*) 0x000DE466,
        .NtCreateProcessEx         = (void*) 0x000DE3BE,
        .NtCreateSection           = (void*) 0x000B8058,
        .NtTerminateProcess        = (void*) 0x000DFAC2,
        .NtQueryInformationFile    = (void*) 0x0008A43E,
        .NtQueryKey                = (void*) 0x0012D52A,
        .NtQueryValueKey           = (void*) 0x0012A324,
        .NtSetInformationFile      = (void*) 0x0008AA2E,
        .NtSetValueKey             = (void*) 0x0012A8E8,
        .ObpFreeObject             = (void*) 0x000CE6D4,
        .PspTerminateProcess       = (void*) 0x000DFC34,
        .swprintf                  = (void*) 0x00058560,
        .ZwOpenProcess             = (void*) 0x000251F0,
        .ZwProtectVirtualMemory    = (void*) 0x0002531C,
        .ZwReadVirtualMemory       = (void*) 0x000256F0,
      }
    },
    {
      TEXT("ntoskrnl 5.1.2600.1634 (xpsp2.050301-1526)"),
      0x422517E4,
      {
        .NtCreateProcess           = (void*) 0x000D3DCD,
        .NtCreateProcessEx         = (void*) 0x000A0107,
        .NtCreateSection           = (void*) 0x0007ECC9,
        .NtTerminateProcess        = (void*) 0x000A156E,
        .NtQueryInformationFile    = (void*) 0x000932EE,
        .NtQueryKey                = (void*) 0x00096734,
        .NtQueryValueKey           = (void*) 0x0008A214,
        .NtSetInformationFile      = (void*) 0x00087FCF,
        .NtSetValueKey             = (void*) 0x000A5C94,
        .ObpFreeObject             = (void*) 0x0007D9A5,
        .PspTerminateProcess       = (void*) 0x000F779C,
        .swprintf                  = (void*) 0x0001F96F,
        .ZwOpenProcess             = (void*) 0x00005682,
        .ZwProtectVirtualMemory    = (void*) 0x000057AE,
        .ZwReadVirtualMemory       = (void*) 0x00005B82,
      }
    },
    {
      TEXT("ntkrnlpa 5.1.2600.2180 (xpsp_sp2_rtm.040803-2158)"),
      0x41107B0C,
      {
        .NtCreateProcess           = (void*) 0x000EECE8,
        .NtCreateProcessEx         = (void*) 0x000EEC32,
        .NtCreateSection           = (void*) 0x000C823E,
        .NtTerminateProcess        = (void*) 0x000F04C8,
        .NtQueryInformationFile    = (void*) 0x00097B16,
        .NtQueryKey                = (void*) 0x0014328C,
        .NtQueryValueKey           = (void*) 0x0013FC8C,
        .NtSetInformationFile      = (void*) 0x0009811A,
        .NtSetValueKey             = (void*) 0x00140292,
        .ObpFreeObject             = (void*) 0x000DE212,
        .PspTerminateProcess       = (void*) 0x000F0642,
        .swprintf                  = (void*) 0x0005FBA5,
        .ZwOpenProcess             = (void*) 0x00026BFC,
        .ZwProtectVirtualMemory    = (void*) 0x00026D28,
        .ZwReadVirtualMemory       = (void*) 0x000270FC,
      }
    },
    {
      TEXT("ntkrnlmp 5.1.2600.2180 (xpsp_sp2_rtm.040803-2158)"),
      0x41107FAA,
      {
        .NtCreateProcess           = (void*) 0x000DDA28,
        .NtCreateProcessEx         = (void*) 0x000B45EC,
        .NtCreateSection           = (void*) 0x00097E25,
        .NtTerminateProcess        = (void*) 0x000B5E75,
        .NtQueryInformationFile    = (void*) 0x000A9C35,
        .NtQueryKey                = (void*) 0x000A329E,
        .NtQueryValueKey           = (void*) 0x0009D361,
        .NtSetInformationFile      = (void*) 0x000AB2C9,
        .NtSetValueKey             = (void*) 0x000AD921,
        .ObpFreeObject             = (void*) 0x00097640,
        .PspTerminateProcess       = (void*) 0x0015F016,
        .swprintf                  = (void*) 0x000236A5,
        .ZwOpenProcess             = (void*) 0x0000D110,
        .ZwProtectVirtualMemory    = (void*) 0x0000D26E,
        .ZwReadVirtualMemory       = (void*) 0x0000D6C9,
      }
    },
    {
      TEXT("ntkrpamp 5.1.2600.2180 (xpsp_sp2_rtm.040803-2158)"),
      0x41107B0D,
      {
        .NtCreateProcess           = (void*) 0x000F8A1C,
        .NtCreateProcessEx         = (void*) 0x000F8966,
        .NtCreateSection           = (void*) 0x000D2DEE,
        .NtTerminateProcess        = (void*) 0x000FA170,
        .NtQueryInformationFile    = (void*) 0x000A27F8,
        .NtQueryKey                = (void*) 0x0014C702,
        .NtQueryValueKey           = (void*) 0x00149102,
        .NtSetInformationFile      = (void*) 0x000A2DC4,
        .NtSetValueKey             = (void*) 0x00149708,
        .ObpFreeObject             = (void*) 0x000E874E,
        .PspTerminateProcess       = (void*) 0x000FA2EA,
        .swprintf                  = (void*) 0x00063635,
        .ZwOpenProcess             = (void*) 0x00028A28,
        .ZwProtectVirtualMemory    = (void*) 0x00028B54,
        .ZwReadVirtualMemory       = (void*) 0x00028F28,
      }
    },
    {
      TEXT("ntoskrnl 5.1.2600.2180 (xpsp_sp2_rtm.040803-2158)"),
      0x41108004,
      {
        .NtCreateProcess           = (void*) 0x000DC543,
        .NtCreateProcessEx         = (void*) 0x000B15D3,
        .NtCreateSection           = (void*) 0x0008DB1B,
        .NtTerminateProcess        = (void*) 0x000B3E1E,
        .NtQueryInformationFile    = (void*) 0x0009BD12,
        .NtQueryKey                = (void*) 0x00098473,
        .NtQueryValueKey           = (void*) 0x000949A8,
        .NtSetInformationFile      = (void*) 0x000A2E7E,
        .NtSetValueKey             = (void*) 0x0009E527,
        .ObpFreeObject             = (void*) 0x0008CEA0,
        .PspTerminateProcess       = (void*) 0x00155BC2,
        .swprintf                  = (void*) 0x0002043A,
        .ZwOpenProcess             = (void*) 0x00006724,
        .ZwProtectVirtualMemory    = (void*) 0x00006882,
        .ZwReadVirtualMemory       = (void*) 0x00006CDD,
      }
    },
    {
      TEXT("ntkrnlmp 5.1.2600.2622 (xpsp_sp2_gdr.050301-1519)"),
      0x42250F77,
      {
        .NtCreateProcess           = (void*) 0x000DD0C0,
        .NtCreateProcessEx         = (void*) 0x000B3CC0,
        .NtCreateSection           = (void*) 0x00095E25,
        .NtTerminateProcess        = (void*) 0x000B5549,
        .NtQueryInformationFile    = (void*) 0x000A7CAB,
        .NtQueryKey                = (void*) 0x000A0FFA,
        .NtQueryValueKey           = (void*) 0x0009B100,
        .NtSetInformationFile      = (void*) 0x000AB9EE,
        .NtSetValueKey             = (void*) 0x000A8F03,
        .ObpFreeObject             = (void*) 0x00095640,
        .PspTerminateProcess       = (void*) 0x0015CFF8,
        .swprintf                  = (void*) 0x0002388A,
        .ZwOpenProcess             = (void*) 0x0000CC0A,
        .ZwProtectVirtualMemory    = (void*) 0x0000CD36,
        .ZwReadVirtualMemory       = (void*) 0x0000D10A,
      }
    },
    {
      TEXT("ntkrnlpa 5.1.2600.2622 (xpsp_sp2_gdr.050301-1519)"),
      0x42250A1D,
      {
        .NtCreateProcess           = (void*) 0x000EECC6,
        .NtCreateProcessEx         = (void*) 0x000EEC10,
        .NtCreateSection           = (void*) 0x000C8222,
        .NtTerminateProcess        = (void*) 0x000F04A6,
        .NtQueryInformationFile    = (void*) 0x00097B00,
        .NtQueryKey                = (void*) 0x00143294,
        .NtQueryValueKey           = (void*) 0x0013FC94,
        .NtSetInformationFile      = (void*) 0x00098104,
        .NtSetValueKey             = (void*) 0x0014029A,
        .ObpFreeObject             = (void*) 0x000DE1F6,
        .PspTerminateProcess       = (void*) 0x000F0620,
        .swprintf                  = (void*) 0x0005FBA5,
        .ZwOpenProcess             = (void*) 0x00026BFC,
        .ZwProtectVirtualMemory    = (void*) 0x00026D28,
        .ZwReadVirtualMemory       = (void*) 0x000270FC,
      }
    },
    {
      TEXT("ntoskrnl 5.1.2600.2622 (xpsp_sp2_gdr.050301-1519)"),
      0x42250FF9,
      {
        .NtCreateProcess           = (void*) 0x000D6314,
        .NtCreateProcessEx         = (void*) 0x000A941A,
        .NtCreateSection           = (void*) 0x0008D41B,
        .NtTerminateProcess        = (void*) 0x000ABC2B,
        .NtQueryInformationFile    = (void*) 0x0009B40A,
        .NtQueryKey                = (void*) 0x00097B71,
        .NtQueryValueKey           = (void*) 0x000940BB,
        .NtSetInformationFile      = (void*) 0x000A0E2C,
        .NtSetValueKey             = (void*) 0x0009DC1D,
        .ObpFreeObject             = (void*) 0x0008C7A1,
        .PspTerminateProcess       = (void*) 0x001554A6,
        .swprintf                  = (void*) 0x0001C047,
        .ZwOpenProcess             = (void*) 0x00006044,
        .ZwProtectVirtualMemory    = (void*) 0x00006170,
        .ZwReadVirtualMemory       = (void*) 0x00006544,
      }
    },
    {
      TEXT("ntkrpamp 5.1.2600.2622 (xpsp_sp2_gdr.050301-1519)"),
      0x42250A1E,
      {
        .NtCreateProcess           = (void*) 0x000F8A1C,
        .NtCreateProcessEx         = (void*) 0x000F8966,
        .NtCreateSection           = (void*) 0x000D2DE6,
        .NtTerminateProcess        = (void*) 0x000FA16E,
        .NtQueryInformationFile    = (void*) 0x000A27E2,
        .NtQueryKey                = (void*) 0x0014C708,
        .NtQueryValueKey           = (void*) 0x00149108,
        .NtSetInformationFile      = (void*) 0x000A2DAE,
        .NtSetValueKey             = (void*) 0x0014970E,
        .ObpFreeObject             = (void*) 0x000E8746,
        .PspTerminateProcess       = (void*) 0x000FA2E8,
        .swprintf                  = (void*) 0x00063635,
        .ZwOpenProcess             = (void*) 0x00028A28,
        .ZwProtectVirtualMemory    = (void*) 0x00028B54,
        .ZwReadVirtualMemory       = (void*) 0x00028F28,
      }
    },
    {
      TEXT("ntkrnlpa 5.1.2600.2622 (xpsp.050301-1521))"),
      0x42250A95,
      {
        .NtCreateProcess           = (void*) 0x000EECE4,
        .NtCreateProcessEx         = (void*) 0x000EEC2E,
        .NtCreateSection           = (void*) 0x000C8212,
        .NtTerminateProcess        = (void*) 0x000F04C4,
        .NtQueryInformationFile    = (void*) 0x00097B00,
        .NtQueryKey                = (void*) 0x001432B2,
        .NtQueryValueKey           = (void*) 0x0013FCB2,
        .NtSetInformationFile      = (void*) 0x00098104,
        .NtSetValueKey             = (void*) 0x001402B8,
        .ObpFreeObject             = (void*) 0x000DE1E6,
        .PspTerminateProcess       = (void*) 0x000F063E,
        .swprintf                  = (void*) 0x0005FBB5,
        .ZwOpenProcess             = (void*) 0x00026C10,
        .ZwProtectVirtualMemory    = (void*) 0x00026D3C,
        .ZwReadVirtualMemory       = (void*) 0x00027110,
      }
    },
    {
      TEXT("ntoskrnl 5.1.2600.2622 (xpsp.050301-1521)"),
      0x42251106,
      {
        .NtCreateProcess           = (void*) 0x000D633C,
        .NtCreateProcessEx         = (void*) 0x000A941A,
        .NtCreateSection           = (void*) 0x0008D41B,
        .NtTerminateProcess        = (void*) 0x000ABC2B,
        .NtQueryInformationFile    = (void*) 0x0009B40A,
        .NtQueryKey                = (void*) 0x00097B71,
        .NtQueryValueKey           = (void*) 0x000940BB,
        .NtSetInformationFile      = (void*) 0x000A0E2C,
        .NtSetValueKey             = (void*) 0x0009DC1D,
        .ObpFreeObject             = (void*) 0x0008C7A1,
        .PspTerminateProcess       = (void*) 0x001554FA,
        .swprintf                  = (void*) 0x0001C047,
        .ZwOpenProcess             = (void*) 0x00006044,
        .ZwProtectVirtualMemory    = (void*) 0x00006170,
        .ZwReadVirtualMemory       = (void*) 0x00006544,
      }
    },
    {
      TEXT("ntkrnlpa 5.2.3790.0 (srv03_rtm.030324-2048)"),
      0x3E800012,
      {
        .NtCreateProcess           = (void*) 0x0011CFC8,
        .NtCreateProcessEx         = (void*) 0x0011CF20,
        .NtCreateSection           = (void*) 0x000F4CDC,
        .NtTerminateProcess        = (void*) 0x0011E640,
        .NtQueryInformationFile    = (void*) 0x000C0004,
        .NtQueryKey                = (void*) 0x00093D5E,
        .NtQueryValueKey           = (void*) 0x00093FDE,
        .NtSetInformationFile      = (void*) 0x000C05B2,
        .NtSetValueKey             = (void*) 0x00090DC4,
        .ObpFreeObject             = (void*) 0x0010CA98,
        .PspTerminateProcess       = (void*) 0x0011E7D4,
        .swprintf                  = (void*) 0x00061F06,
        .ZwOpenProcess             = (void*) 0x00027BD0,
        .ZwProtectVirtualMemory    = (void*) 0x00027CFC,
        .ZwReadVirtualMemory       = (void*) 0x000280F8,
      }
    },
    {
      TEXT("ntoskrnl 5.2.3790.0 (srv03_rtm.030324-2048)"),
      0x3E800A79,
      {
        .NtCreateProcess           = (void*) 0x000DF684,
        .NtCreateProcessEx         = (void*) 0x000B0FE3,
        .NtCreateSection           = (void*) 0x00095ECA,
        .NtTerminateProcess        = (void*) 0x000B2CBA,
        .NtQueryInformationFile    = (void*) 0x000A72CF,
        .NtQueryKey                = (void*) 0x000A2C31,
        .NtQueryValueKey           = (void*) 0x00099D61,
        .NtSetInformationFile      = (void*) 0x0009A747,
        .NtSetValueKey             = (void*) 0x000B4859,
        .ObpFreeObject             = (void*) 0x00095231,
        .PspTerminateProcess       = (void*) 0x000D3B76,
        .swprintf                  = (void*) 0x0002D6A9,
        .ZwOpenProcess             = (void*) 0x000081D2,
        .ZwProtectVirtualMemory    = (void*) 0x00008330,
        .ZwReadVirtualMemory       = (void*) 0x000087B8,
      }
    },
  } ;


/******************************************************************/
/* Exported function                                              */
/******************************************************************/

NTSTATUS NtUndoc_Init() 
{
  IMGINFO   imgInfo ;

  PBYTE     pKernelBase = NULL ;
  ULONG     nKernelSize = 0 ;
  
  INT       iVersion ;
  INT       iDetectedVersion = -1 ;
  INT       iFunc ;

  SystInfo_GetModuleBase (NULL, (void**)&pKernelBase, &nKernelSize) ;

  TRACE_INFO(TEXT("Kernel base : 0x%08X\n"), pKernelBase) ;
  TRACE_INFO(TEXT("Kernel size : 0x%08X\n"), nKernelSize) ;

  if( ! ImgInfo_GetInfo (&imgInfo, pKernelBase, nKernelSize) )
    {
      TRACE_ERROR (TEXT("ImgInfo_GetInfo failed\n")) ;
      return STATUS_UNSUCCESSFUL ;
    }

  TRACE_INFO(TEXT("Image time stamp = 0x%08X\n"), imgInfo.dwTimeStamp) ;
  TRACE_INFO(TEXT("Image check sum = 0x%08X\n"), imgInfo.dwCheckSum) ;

  for( iVersion=0 ; iVersion<arraysize(g_aOsVersion) ; iVersion++ )
    {
      TRACE_INFO (TEXT("Checking %s...\n"), g_aOsVersion[iVersion].szOsVersion) ;

      if( g_aOsVersion[iVersion].dwTimeStamp != imgInfo.dwTimeStamp )
        {
          TRACE_INFO (TEXT("Time stamp doesn't match\n")) ;
          continue ;
        }

      TRACE_INFO (TEXT("Windows version matches !\n")) ;
      iDetectedVersion = iVersion ;
      break ;
    }

  if( iDetectedVersion<0 )
    {
      TRACE_ERROR(TEXT("Windows version not supported\n")) ;
      return STATUS_UNSUCCESSFUL ;
    }

  TRACE_ALWAYS (TEXT("Detected Windows version : %s\n"), g_aOsVersion[iDetectedVersion].szOsVersion) ;

  for( iFunc=0 ; iFunc<sizeof(ntundoc)/sizeof(void*) ; iFunc++ )
  {
    int nOffset = ((INT_PTR*)&g_aOsVersion[iDetectedVersion].offsets)[iFunc] ;
    ((BYTE**)&ntundoc)[iFunc] = nOffset ? pKernelBase+nOffset : NULL ;
  }

  return STATUS_SUCCESS ;
}
